﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Atosenet.Data
{
    public struct IEEEAddress
    {
        #region 成员

        public const int IEEE_ADDRESS_LENGTH = 8;

        public static readonly IEEEAddress Empty = new IEEEAddress(new byte[IEEE_ADDRESS_LENGTH]);

        private byte[] _rfData;

        #endregion


        #region 初始化

        public IEEEAddress(byte[] data)
        {
            _rfData = new byte[IEEE_ADDRESS_LENGTH];

            if (data == null || data.Length != IEEE_ADDRESS_LENGTH)
                return;

            _rfData = data;
        }

        #endregion


        #region 公开函数

        public override string ToString()
        {
            return string.Format("IEEE Address({0}{1}.{2}{3}.{4}{5}.{6}{7})",
                 _rfData[0].ToString("X2"),
                 _rfData[1].ToString("X2"),
                 _rfData[2].ToString("X2"),
                 _rfData[3].ToString("X2"),
                 _rfData[4].ToString("X2"),
                 _rfData[5].ToString("X2"),
                 _rfData[6].ToString("X2"),
                 _rfData[7].ToString("X2"));
        }

        public string ToString(string format)
        {
            switch (format.ToUpper())
            {
                case "S":
                    return string.Format("{0}{1}.{2}{3}.{4}{5}.{6}{7}",
                     _rfData[0].ToString("X2"),
                     _rfData[1].ToString("X2"),
                     _rfData[2].ToString("X2"),
                     _rfData[3].ToString("X2"),
                     _rfData[4].ToString("X2"),
                     _rfData[5].ToString("X2"),
                     _rfData[6].ToString("X2"),
                     _rfData[7].ToString("X2"));
                default:
                    return ToString();
            }
        }

        #endregion


        #region 静态函数

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
                return false;

            IEEEAddress address = (IEEEAddress)obj;
            return (address.GetHashCode() == this.GetHashCode());
        }

        public override int GetHashCode()
        {
            int result = 0;

            for (int i = 0; i < this.RfData.Length; i++)
            {
                result += (int)(Math.Pow(10, i) * this.RfData[i]);
            }
            return result;
        }

        public static bool IsEmpty(IEEEAddress address)
        {
            return address == IEEEAddress.Empty;
        }

        public static bool operator ==(IEEEAddress address1, IEEEAddress address2)
        {
            if (address1.RfData.Length != address2.RfData.Length)
                return false;

            for (int i = 0; i < address1.RfData.Length; i++)
            {
                if (address1.RfData[i] != address2.RfData[i])
                    return false;
            }
            return true;
        }

        public static bool operator !=(IEEEAddress address1, IEEEAddress address2)
        {
            return !(address1 == address2);
        }       

        #endregion


        #region 属性

        public byte[] RfData
        {
            get { return _rfData; }
        }

        public UInt16 GroupID
        {
            get { return Converter.ConvertToUInt16BE(_rfData, 4); }
            set { Converter.ConvertToByteArrayBE(value, ref _rfData, 4); }
        }

        public UInt16 NodeID
        {
            get { return Converter.ConvertToUInt16BE(_rfData, 6); }
            set { Converter.ConvertToByteArrayBE(value, ref _rfData, 6); }
        }

        public int Length
        {
            get { return IEEE_ADDRESS_LENGTH; }
        }

        #endregion
    }
}
